classdef Test_plotlyfig < matlab.unittest.TestCase
    methods (Test)
        function testLinePlotData(tc)
            fig = figure("Visible","off");
            y = [0.0301 0.4411 0.7007 0.7030 0.5102 0.6122 0.7464 0.8014 0.3367 0.5641];
            x = 1:10;
            plot(x,y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = '', ...
                mode = 'lines', ...
                x = x, ...
                y = y, ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testLinePlotLayout(tc)
            fig = figure("Visible","off");
            y = [0.0301 0.4411 0.7007 0.7030 0.5102 0.6122 0.7464 0.8014 0.3367 0.5641];
            x = 1:10;
            plot(x,y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyEqual(p.layout, struct( ...
                autosize = false, ...
                margin = struct( ...
                    pad = 0, ...
                    l = 0, ...
                    r = 0, ...
                    b = 0, ...
                    t = 0 ...
                ), ...
                showlegend = false, ...
                width = 840, ...
                height = 630, ...
                paper_bgcolor = "rgb(255,255,255)", ...
                hovermode = 'closest', ...
                xaxis1 = struct( ...
                    side = 'bottom', ...
                    zeroline = false, ...
                    autorange = false, ...
                    linecolor = "rgb(38,38,38)", ...
                    linewidth = 1, ...
                    exponentformat = 'none', ...
                    tickfont = struct( ...
                        size = 10, ...
                        family = "Arial, sans-serif", ...
                        color = "rgb(38,38,38)" ...
                    ), ...
                    ticklen = 6.51, ...
                    tickcolor = "rgb(38,38,38)", ...
                    tickwidth = 1, ...
                    tickangle = 0, ...
                    ticks = "inside", ...
                    showgrid = false, ...
                    gridcolor = "rgba(38,38,38,0.150000)", ...
                    type = 'linear', ...
                    showticklabels = true, ...
                    tickmode = "array", ...
                    tickvals = [1 2 3 4 5 6 7 8 9 10], ...
                    range = [1 10], ...
                    mirror = "ticks", ...
                    ticktext = {{'1'; '2'; '3'; '4'; '5'; '6'; '7'; '8'; '9'; '10'}}, ...
                    titlefont = struct( ...
                        color = "rgb(38,38,38)", ...
                        family = "Arial, sans-serif", ...
                        size = 11 ...
                    ), ...
                    showline = true, ...
                    domain = [0.13 0.905], ...
                    anchor = "y1" ...
                ), ...
                scene1 = struct( ...
                    domain = struct( ...
                        x = [0.13 0.905], ...
                        y = [0.11 0.925] ...
                    ) ...
                ), ...
                yaxis1 = struct( ...
                    side = 'left', ...
                    zeroline = false, ...
                    autorange = false, ...
                    linecolor = "rgb(38,38,38)", ...
                    linewidth = 1, ...
                    exponentformat = 'none', ...
                    tickfont = struct( ...
                        size = 10, ...
                        family = "Arial, sans-serif", ...
                        color = "rgb(38,38,38)" ...
                    ), ...
                    ticklen = 6.51, ...
                    tickcolor = "rgb(38,38,38)", ...
                    tickwidth = 1, ...
                    tickangle = 0, ...
                    ticks = "inside", ...
                    showgrid = false, ...
                    gridcolor = "rgba(38,38,38,0.150000)", ...
                    type = 'linear', ...
                    showticklabels = true, ...
                    tickmode = "array", ...
                    tickvals = [0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9], ...
                    range = [0 0.9], ...
                    mirror = "ticks", ...
                    ticktext = {{'0'; '0.1'; '0.2'; '0.3'; '0.4'; '0.5'; '0.6'; '0.7'; '0.8'; '0.9'}}, ...
                    titlefont = struct( ...
                        color = "rgb(38,38,38)", ...
                        family = "Arial, sans-serif", ...
                        size = 11 ...
                    ), ...
                    showline = true, ...
                    domain = [0.11 0.925], ...
                    anchor = "x1" ...
                ), ...
                annotations = {{struct( ...
                    showarrow = false, ...
                    xref = "paper", ...
                    yref = "paper", ...
                    xanchor = 'center', ...
                    align = 'center', ...
                    yanchor = "bottom", ...
                    text = "<b><b></b></b>", ...
                    x = 0.5175, ...
                    y = 0.935, ...
                    font = struct( ...
                        color = "rgb(0,0,0)", ...
                        family = "Arial, sans-serif", ...
                        size = 11 ...
                    ), ...
                    bordercolor = "rgba(0,0,0,0)", ...
                    textangle = 0, ...
                    borderwidth = 0.5, ...
                    borderpad = 3 ...
                )}} ...
            ), AbsTol=1e-15);
        end

        function testAreaPlotData(tc)
            fig = figure("Visible","off");
            y = [0.6297 0.9559 0.7551 0.5261 0.8501 0.8160 0.1321 0.7607 0.6172 0.3976];
            x = 1:10;
            area(x,y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "scatter", ...
                x = x, ...
                y = y, ...
                name = '', ...
                visible = true, ...
                fill = "tozeroy", ...
                mode = "lines", ...
                line = struct( ...
                    color = "rgba(0,0,0,1.000000)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                fillcolor = "rgba(0,114,189,1.000000)", ...
                showlegend = true ...
            ));
        end

        function testScatterPlotData(tc)
            fig = figure("Visible","off");
            x = linspace(0,3*pi,200);
            y = cos(x) + rand(1,200);
            scatter(x,y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                mode = "markers", ...
                visible = true, ...
                name = '', ...
                x = x, ...
                y = y, ...
                marker = struct( ...
                    sizeref = 1, ...
                    sizemode = "area", ...
                    size = 36 * ones(size(x)), ...
                    line = struct( ...
                        width = 0.7500, ...
                        color = "rgb(0,114,189)" ...
                    ), ...
                    symbol = "circle", ...
                    color = "rgba(0,0,0,0)", ...
                    opacity = 1 ...
                ), ...
                showlegend = false ...
            ));
        end

        function testSingleScatterPlotData(tc)
            fig = figure("Visible","off");
            x = 1;
            y = 1;
            scatter(x,y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                mode = "markers", ...
                visible = true, ...
                name = '', ...
                x = {{x}}, ...
                y = {{y}}, ...
                marker = struct( ...
                    sizeref = 1, ...
                    sizemode = "area", ...
                    size = {{36}}, ...
                    line = struct( ...
                        width = 0.7500, ...
                        color = "rgb(0,114,189)" ...
                    ), ...
                    symbol = "circle", ...
                    color = "rgba(0,0,0,0)", ...
                    opacity = 1 ...
                ), ...
                showlegend = false ...
            ));
        end

        function testScatter3DPlotData(tc)
            fig = figure("Visible","off");
            [X,Y,Z] = sphere(16);
            x = [0.5*X(:); 0.75*X(:); X(:)]';
            y = [0.5*Y(:); 0.75*Y(:); Y(:)]';
            z = [0.5*Z(:); 0.75*Z(:); Z(:)]';
            scatter3(x,y,z);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter3d", ...
                scene = "scene1", ...
                mode = "markers", ...
                visible = true, ...
                name = '', ...
                x = x, ...
                y = y, ...
                z = z, ...
                marker = struct( ...
                    sizeref = 1, ...
                    sizemode = "area", ...
                    size = 72 * ones(size(x)), ...
                    line = struct( ...
                        width = 0.7500, ...
                        color = "rgb(0,114,189)" ...
                    ), ...
                    symbol = "circle", ...
                    color = "rgba(0,0,0,0)", ...
                    opacity = 1 ...
                ), ...
                showlegend = false ...
            ));
        end

        function testSurfacePlotData(tc)
            fig = figure("Visible","off");
            points = linspace(-2, 2, 40);
            [x, y] = meshgrid(points, points);
            z = 2./exp((x-0.5).^2+y.^2)-2./exp((x+0.5).^2+y.^2);
            surf(x, y, z)

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(rmfield(p.data{1}, ["colorscale" "surfacecolor"]), struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "surface", ...
                x = x, ...
                y = y, ...
                z = z, ...
                contours = struct( ...
                    x = struct( ...
                        "end", 2, ...
                        start = -2, ...
                        size = 0.102564102564103, ...
                        show = true, ...
                        color = "black" ...
                    ), ...
                    y = struct( ...
                        "end", 2, ...
                        start = -2, ...
                        size = 0.102564102564103, ...
                        show = true, ...
                        color = "black" ...
                    ) ...
                ), ...
                name = '', ...
                showscale = false, ...
                visible = true, ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testPolarScatterData(tc)
            fig = figure("Visible","off");
            t = pi/4:pi/4:2*pi;
            r = [19 6 12 18 16 11 15 15];
            polarscatter(t,r)

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                subplot = 'polar2', ...
                type = 'scatterpolar', ...
                visible = true, ...
                name = '', ...
                r = r, ...
                theta = rad2deg(t), ...
                mode = 'markers', ...
                marker = struct( ...
                    sizeref = 1, ...
                    sizemode = "area", ...
                    size = [36 36 36 36 36 36 36 36], ...
                    line = struct( ...
                        width = 0.75, ...
                        color = "rgb(0,114,189)" ...
                    ), ...
                    symbol = "circle", ...
                    color = "rgba(0,0,0,0)", ...
                    opacity = 1 ...
                ), ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testPolarPlotData(tc)
            fig = figure("Visible","off");
            t = 0:0.01:2*pi;
            r = abs(sin(2*t).*cos(2*t));
            polarplot(t, r)

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                subplot = 'polar2', ...
                type = 'scatterpolar', ...
                visible = true, ...
                name = '', ...
                r = r, ...
                theta = rad2deg(t), ...
                mode = 'lines', ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 1, ...
                    dash = "solid" ...
                ), ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testComplexPolarPlotData(tc)
            fig = figure("Visible","off");
            Z = [2+3i 2 -1+4i 3-4i 5+2i -4-2i -2+3i -2 -3i 3i-2i];
            polarplot(Z,'*')

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                subplot = 'polar2', ...
                type = 'scatterpolar', ...
                visible = true, ...
                name = '', ...
                r = fig.Children.Children.RData, ...
                theta = rad2deg(fig.Children.Children.ThetaData), ...
                mode = 'markers', ...
                marker = struct( ...
                    size = 3.6, ...
                    symbol = "asterisk-open", ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                line = struct(), ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testHistogramPlotData(tc)
            fig = figure("Visible","off");
            values = [0.6297 0.9559 0.7551 0.5261 0.8501 0.8160 0.1321 0.7607 0.6172 0.3976];
            histogram(values);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                x = [0.15 0.45 0.75 1.05], ...
                width = [0.3 0.3 0.3 0.3], ...
                y = [1 2 6 1], ...
                name = 'values', ...
                marker = struct( ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgba(0,0,0,1.000000)" ...
                    ), ...
                    color = "rgba(0,114,189,0.600000)" ...
                ), ...
                opacity = 0.75, ...
                visible = true, ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testPolarHistogramPlotData(tc)
            fig = figure("Visible","off");
            values = [0.6297 0.9559 0.7551 0.5261 0.8501 0.8160 0.1321 0.7607 0.6172 0.3976];
            polarhistogram(values);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "barpolar", ...
                r = [1 6 3 0], ...
                width = [22.5 22.5 22.5 22.5], ...
                theta = [11.25 33.75 56.25 78.75], ...
                name = 'values', ...
                marker = struct( ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgba(0,0,0,1.000000)" ...
                    ), ...
                    color = "rgba(0,114,189,0.600000)" ...
                ), ...
                opacity = 0.6, ...
                visible = true, ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testEasyToUsePolarPlotData(tc)
            fig = figure("Visible","off");
            ezpolar("1+cos(theta)")

            p = plotlyfig(fig,"visible","off","treatAs",'ezpolar');

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(rmfield(p.data{1},["r" "theta"]), struct( ...
                type = "scatterpolar", ...
                subplot = "polar2", ...
                visible = true, ...
                name = '', ...
                mode = 'lines', ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.75, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testLogLogPlot(tc)
            fig = figure("Visible","off");
            zeta = 0.5; % damping factor
            color = "r";
            w = logspace(-1, 1, 1000); % values equally spaced logarithmically
            a = w.^2 - 1;
            b = 2*w*zeta;
            gain = sqrt(1./(a.^2 + b.^2));
            loglog(w, gain, color=color);
            axis([0.1 10 0.01 100]);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                name = '', ...
                mode = 'lines', ...
                x = w, ...
                y = gain, ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(255,0,0)" ...
                ), ...
                line = struct( ...
                    color = "rgb(255,0,0)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                visible = true, ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testSingleBarPlotData(tc)
            fig = figure("Visible","off");
            bar(1,1);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                name = '', ...
                visible = true, ...
                orientation = "v", ...
                x = {{1}}, ...
                y = {{1}}, ...
                marker = struct( ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgba(0,0,0,1.000000)", ...
                        dash = "solid" ...
                    ), ...
                    color = "rgba(0,114,189,1.000000)" ...
                ), ...
                showlegend = true ...
            ));
        end

        function testDateBarPlotData(tc)
            fig = figure("Visible","off");
            x = datetime("today");
            y = 1;
            bar(x,y)

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                name = '', ...
                visible = true, ...
                orientation = "v", ...
                x = {{x}}, ...
                y = {{y}}, ...
                marker = struct( ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgba(0,0,0,1.000000)", ...
                        dash = "solid" ...
                    ), ...
                    color = "rgba(0,114,189,1.000000)" ...
                ), ...
                showlegend = true ...
            ));
        end

        function testVerticalBarPlotData(tc)
            fig = figure("Visible","off");
            x = 1:12;
            y = [38556 24472 14556 18060 19549 8122 28541 7880 3283 4135 7953 1884];
            bar(x,y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                name = '', ...
                visible = true, ...
                orientation = "v", ...
                x = x, ...
                y = y, ...
                marker = struct( ...
                    line = struct( ...
                        color = "rgba(0,0,0,1.000000)", ...
                        width = 0.5, ...
                        dash = "solid" ...
                    ), ...
                    color = "rgba(0,114,189,1.000000)" ...
                ), ...
                showlegend = true ...
            ));
        end

        function testHorizontalBarPlotData(tc)
            fig = figure("Visible","off");
            x = 1:12;
            y = [38556 24472 14556 18060 19549 8122 28541 7880 3283 4135 7953 1884];
            barh(x,y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                name = '', ...
                visible = true, ...
                orientation = "h", ...
                x = y, ...
                y = x, ...
                marker = struct( ...
                    line = struct( ...
                        color = "rgba(0,0,0,1.000000)", ...
                        width = 0.5, ...
                        dash = "solid" ...
                    ), ...
                    color = "rgba(0,114,189,1.000000)" ...
                ), ...
                showlegend = true ...
            ));
        end

        function testPieChartPlotData(tc)
            fig = figure("Visible","off");
            count = [35 29 28 40 27 30 34 28 36 29 29 30 31 60 90];
            label = 1:15;
            pie(count,label);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 15);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = 'scatter', ...
                x = [-0.0196 -0.0196 -0.0761 -0.1324 -0.1883 -0.2437 -0.2984 -0.3522 -0.4049 -0.0196 -0.0196], ...
                y = [0.0981 1.0981 1.0965 1.0917 1.0837 1.0726 1.0584 1.0411 1.0208 0.0981 0.0981], ...
                name = '', ...
                visible = true, ...
                fill = 'tozeroy', ...
                mode = 'lines', ...
                marker = struct( ...
                    sizeref = 1, ...
                    sizemode = "diameter", ...
                    size = 6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,0)" ...
                ), ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                fillcolor = "rgba(62,38,168,1.000000)", ...
                showlegend = false ...
            ), AbsTol=1e-4);
        end

        function testStairsPlotData(tc)
            fig = figure("Visible","off");
            x = 2:2:8;
            y = [1 1 2 2];
            stairs(x,y,'-or')

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = '', ...
                mode = 'lines+markers', ...
                x = x, ...
                y = y, ...
                line = struct( ...
                    color = "rgb(255,0,0)", ...
                    width = 0.5, ...
                    dash = "solid", ...
                    shape = "hv" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgb(255,0,0)" ...
                    ), ...
                    color = "rgba(0,0,0,0)" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-4);
        end

        function testPlotmatrixData(tc)
            fig = figure("Visible","off");
            columns = [ ...
                0.67  0.77  0.42;
                0.43  0.70  0.66;
                0.45  0.13  0.72;
                0.61  0.13  0.53;
                0.06  0.09  0.11;
                0.32  0.01  0.63];
            plotmatrix(columns);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 10); % 3x3 matrix of plots + 1 parent plot
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "scatter", ...
                mode = "none", ...
                x = [], ...
                y = [], ...
                name = "", ...
                showlegend = false ...
            ));
            tc.verifyEqual(p.data{2}, struct( ...
                type = "scatter", ...
                xaxis = "x2", ...
                yaxis = "y2", ...
                visible = true, ...
                name = '', ...
                mode = 'markers', ...
                x = columns(:,2)', ...
                y = columns(:,3)', ...
                line = struct(), ...
                marker = struct( ...
                    size = 3, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ));
            tc.verifyEqual(p.data{3}, struct( ...
                type = "scatter", ...
                xaxis = "x3", ...
                yaxis = "y3", ...
                visible = true, ...
                name = '', ...
                mode = 'markers', ...
                x = columns(:,1)', ...
                y = columns(:,3)', ...
                line = struct(), ...
                marker = struct( ...
                    size = 3, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ));
            tc.verifyEqual(p.data{4}, struct( ...
                type = "scatter", ...
                xaxis = "x4", ...
                yaxis = "y4", ...
                visible = true, ...
                name = '', ...
                mode = 'markers', ...
                x = columns(:,3)', ...
                y = columns(:,2)', ...
                line = struct(), ...
                marker = struct( ...
                    size = 3, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ));
            tc.verifyEqual(p.data{5}, struct( ...
                type = "scatter", ...
                xaxis = "x5", ...
                yaxis = "y5", ...
                visible = true, ...
                name = '', ...
                mode = 'markers', ...
                x = columns(:,1)', ...
                y = columns(:,2)', ...
                line = struct(), ...
                marker = struct( ...
                    size = 3, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ));
            tc.verifyEqual(p.data{6}, struct( ...
                type = "scatter", ...
                xaxis = "x6", ...
                yaxis = "y6", ...
                visible = true, ...
                name = '', ...
                mode = 'markers', ...
                x = columns(:,3)', ...
                y = columns(:,1)', ...
                line = struct(), ...
                marker = struct( ...
                    size = 3, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ));
            tc.verifyEqual(p.data{7}, struct( ...
                type = "scatter", ...
                xaxis = "x7", ...
                yaxis = "y7", ...
                visible = true, ...
                name = '', ...
                mode = 'markers', ...
                x = columns(:,2)', ...
                y = columns(:,1)', ...
                line = struct(), ...
                marker = struct( ...
                    size = 3, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ));
            tc.verifyEqual(p.data{8}, struct( ...
                xaxis = "x8", ...
                yaxis = "y8", ...
                type = "bar", ...
                x = [0.25 0.75], ...
                width = [0.5 0.5], ...
                y = [2 4], ...
                name = '', ...
                marker = struct( ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgba(0,0,0,1.000000)" ...
                    ), ...
                    color = "rgba(0,114,189,0.600000)" ...
                ), ...
                opacity = 0.75, ...
                visible = true, ...
                showlegend = true ...
            ));
            tc.verifyEqual(p.data{9}, struct( ...
                xaxis = "x9", ...
                yaxis = "y9", ...
                type = "bar", ...
                x = [0.25 0.75], ...
                width = [0.5 0.5], ...
                y = [4 2], ...
                name = '', ...
                marker = struct( ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgba(0,0,0,1.000000)" ...
                    ), ...
                    color = "rgba(0,114,189,0.600000)" ...
                ), ...
                opacity = 0.75, ...
                visible = true, ...
                showlegend = true ...
            ));
            tc.verifyEqual(p.data{10}, struct( ...
                xaxis = "x10", ...
                yaxis = "y10", ...
                type = "bar", ...
                x = [0.25 0.75], ...
                width = [0.5 0.5], ...
                y = [4 2], ...
                name = '', ...
                marker = struct( ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgba(0,0,0,1.000000)" ...
                    ), ...
                    color = "rgba(0,114,189,0.600000)" ...
                ), ...
                opacity = 0.75, ...
                visible = true, ...
                showlegend = true ...
            ));
        end

        function testContourPlotData(tc)
            fig = figure("Visible","off");
            range = 0:0.1:3;
            [xVals,yVals] = meshgrid(range,range);
            zVals = sin(3*xVals).*cos(xVals+yVals);
            contour(xVals,yVals,zVals);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(rmfield(p.data{1}, "colorscale"), struct( ...
                type = "contour", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                name = '', ...
                visible = true, ...
                xtype = "array", ...
                ytype = "array", ...
                x = range, ...
                y = range', ...
                z = zVals, ...
                autocontour = false, ...
                contours = struct( ...
                    "end", 0.8, ...
                    start = -0.8, ...
                    size = 0.2, ...
                    coloring = "lines", ...
                    showlines = true ...
                ), ...
                zauto = false, ...
                zmin = -0.8, ...
                zmax = 0.8, ...
                showscale = false, ...
                reversescale = false, ...
                line = struct( ...
                    width = 0.75, ...
                    dash = "solid", ...
                    color = "rgba(0,0,0,0)", ...
                    smoothing = 0 ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-16);
        end

        function testFunctionContourPlotData(tc)
            fig = figure("Visible","off");
            fcontour(@(x,y) sin(3*x).*cos(x+y),[0 3 0 3],Fill="on",LineColor="k");
            chartTitle = "f(x,y) = sin(3*x)*cos(x+y)";
            title(chartTitle);
            colormap("spring");

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(rmfield(p.data{1}, ["colorscale" "x" "y" "z"]), struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                name = '{sin}({3} {x}) {cos}({x}+{y})', ...
                type = "contour", ...
                visible = true, ...
                xtype = "array", ...
                ytype = "array", ...
                autocontour = false, ...
                contours = struct( ...
                    "end", 0.8, ...
                    start = -1, ...
                    size = 0.2, ...
                    coloring = "fill" ...
                ), ...
                zauto = false, ...
                zmin = -1, ...
                zmax = 0.8, ...
                showscale = false, ...
                reversescale = false, ...
                line = struct( ...
                    width = 0.5, ...
                    dash = "solid", ...
                    color = "rgb(0,0,0)", ...
                    smoothing = 0 ...
                ), ...
                showlegend = true ...
            ), AbsTol=1e-2);
        end

        function testStemPlotData(tc)
            fig = figure("Visible","off");
            x = 1:10;
            y = rand(10,1);
            stem(x, y, 'filled');

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "scatter", ...
                visible = true, ...
                name = '', ...
                mode = "lines+markers", ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 1, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 1, ...
                        color = {repmat({"rgba(0,0,0,0)" "rgb(0,114,189)" "rgba(0,0,0,0)"},1,10)'} ...
                    ), ...
                    color = {repmat({"rgba(0,0,0,0)" "rgba(0, 0.4470, 0.7410,1)" "rgba(0,0,0,0)"},1,10)'} ...
                ), ...
                x = reshape([x; x; nan(1,length(x))], [], 1), ...
                y = reshape([zeros(1,length(y)); y'; nan(1,length(y))], [], 1), ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testStackedBarData(tc)
            fig = figure("Visible","off");
            data = [10 20 30; 15 25 35; 5 15 25];
            bar(1:3, data, 'stack');

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 3); % One for each stack
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                name = '', ...
                visible = true, ...
                orientation = "v", ...
                x = [1 2 3], ...
                y = [10 15 5], ...
                marker = struct( ...
                    color = "rgba(0,114,189,1.000000)", ...
                    line = struct( ...
                        color = "rgba(0,0,0,1.000000)", ...
                        width = 0.5, ...
                        dash = "solid" ...
                    ) ...
                ), ...
                showlegend = true ...
            ));
            tc.verifyEqual(p.data{2}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                name = '', ...
                visible = true, ...
                orientation = "v", ...
                x = [1 2 3], ...
                y = [20 25 15], ...
                marker = struct( ...
                    color = "rgba(217,83,25,1.000000)", ...
                    line = struct( ...
                        color = "rgba(0,0,0,1.000000)", ...
                        width = 0.5, ...
                        dash = "solid" ...
                    ) ...
                ), ...
                showlegend = true ...
            ));
            tc.verifyEqual(p.data{3}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                name = '', ...
                visible = true, ...
                orientation = "v", ...
                x = [1 2 3], ...
                y = [30 35 25], ...
                marker = struct( ...
                    color = "rgba(237,177,32,1.000000)", ...
                    line = struct( ...
                        color = "rgba(0,0,0,1.000000)", ...
                        width = 0.5, ...
                        dash = "solid" ...
                    ) ...
                ), ...
                showlegend = true ...
            ));
        end

        function testHeatmapData(tc)
            fig = figure(Visible="off");
            data = magic(5);
            heatmap(data);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(rmfield(p.data{1}, "colorscale"), struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "heatmap", ...
                x = {num2cell(num2str((1:5)'))}, ...
                y = {num2cell(num2str(flip(1:5)'))}, ...
                z = flip(data), ...
                zmin = min(data,[],"all"), ...
                zmax = max(data,[],"all"), ...
                connectgaps = false, ...
                hoverongaps = false, ...
                hoverinfo = "text", ...
                text = flip(data), ...
                hoverlabel = struct( ...
                    bgcolor = "white" ...
                ), ...
                showscale = true, ...
                colorbar = struct( ...
                    x = fig.Children.Position(1) + fig.Children.Position(3), ...
                    y = fig.Children.Position(2), ...
                    xanchor = "left", ...
                    yanchor = "bottom", ...
                    thicknessmode = "fraction", ...
                    thickness = fig.Children.Position(3)/10, ...
                    lenmode = "fraction", ...
                    len = fig.Children.Position(4), ...
                    ypad = 0, ...
                    xpad = 10, ...
                    outlinecolor = "rgb(150,150,150)" ...
                ), ...
                visible = true, ...
                opacity = 0.9500, ...
                showlegend = false, ...
                name = "" ...
            ), AbsTol=1e-15);
        end

        function testHeatmapDataColorLimitsOverride(tc)
            fig = figure("Visible","off");
            data = magic(5);
            zmin = -5;
            zmax = 5;
            h = heatmap(data);
            h.ColorLimits = [zmin, zmax];

            p = plotlyfig(fig,"visible","off");

            tc.verifyEqual(p.data{1}.zmin, zmin);
            tc.verifyEqual(p.data{1}.zmax, zmax);
        end

        function testErrorbarData(tc)
            fig = figure("Visible","off");
            x = 1:10;
            y = rand(1,10);
            err = 0.1*ones(1,10);
            errorbar(x,y,err);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = '', ...
                mode = 'lines', ...
                x = x, ...
                y = y, ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false, ...
                error_y = struct( ...
                    visible = true, ...
                    type = "data", ...
                    symmetric = false, ...
                    array = err, ...
                    arrayminus = err, ...
                    thickness = 0.5, ...
                    width = 6, ...
                    color = "rgb(0,114,189)" ...
                ), ...
                error_x = struct( ...
                    visible = true, ...
                    type = "data", ...
                    array = zeros(1,0), ...
                    arrayminus = zeros(1,0), ...
                    thickness = 0.5, ...
                    width = 6, ...
                    color = "rgb(0,114,189)" ...
                ) ...
            ), AbsTol=1e-15);
        end

        function testDoubleYAxisLinePlotData(tc)
            fig = figure("Visible","off");
            x = linspace(0,10);
            y = sin(3*x);
            yyaxis left
            plot(x,y);
            y2 = sin(3*x).*exp(0.5*x);
            yyaxis right
            plot(x,y2);
            ylim([-150 150]);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 4);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = '', ...
                mode = 'lines', ...
                x = x, ...
                y = y, ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{2}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y2", ...
                visible = true, ...
                name = '', ...
                mode = 'lines', ...
                x = x, ...
                y = y2, ...
                line = struct( ...
                    color = "rgb(217,83,25)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(217,83,25)" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testVerticalConstantLinePlotData(tc)
            fig = figure("Visible","off");
            xline(1);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "scatter", ...
                visible = true, ...
                x = [1 1], ...
                y = [0 1], ...
                name = '', ...
                mode = "lines", ...
                line = struct( ...
                    color = "rgb(38,38,38)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testVerticalConstantLineWithLabel(tc)
            fig = figure("Visible","off");
            label = "label";
            alignment = "left";
            width = 3;
            xl = xline(1,'r--',label,LineWidth=width);
            xl.LabelHorizontalAlignment = alignment;

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}.line, struct( ...
                color = "rgb(255,0,0)", ...
                width = width, ...
                dash = "dash" ...
            ));
            tc.verifyTrue(any(cellfun(@(ann) contains(ann.text,label), p.layout.annotations)));
            tc.verifyTrue(any(cellfun(@(ann) ann.xanchor == alignment, p.layout.annotations)));
        end

        function testStackedPlotData(tc)
            fig = figure("Visible","off");
            x = 1:5;
            a = cos(x);
            b = exp(x);
            dt = datetime(2010,1,1) + years(x);
            tb = table(dt',a',b',VariableNames=["date" "a" "b"]);
            stackedplot(tb);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 3);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                visible = true, ...
                name = 'date', ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                x = x, ...
                y = b', ...
                mode = "lines", ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                showlegend = false ...
            ));
            tc.verifyEqual(p.data{2}, struct( ...
                type = "scatter", ...
                visible = true, ...
                name = 'a', ...
                xaxis = "x1", ...
                yaxis = "y2", ...
                x = x, ...
                y = a', ...
                mode = "lines", ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ) ...
            ));
            tc.verifyEqual(p.data{3}, struct( ...
                type = "scatter", ...
                visible = true, ...
                name = 'b', ...
                xaxis = "x1", ...
                yaxis = "y3", ...
                x = x, ...
                y = dt', ...
                mode = "lines", ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ) ...
            ));
        end

        function testDoubleYAxisAreaPlotData(tc)
            fig = figure("Visible","off");
            x = linspace(0,10);
            y = sin(3*x);
            yyaxis left
            area(x,y);
            y2 = sin(3*x).*exp(0.5*x);
            yyaxis right
            area(x,y2);
            ylim([-150 150]);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 4);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "scatter", ...
                x = x, ...
                y = y, ...
                name = '', ...
                visible = true, ...
                fill = "tozeroy", ...
                mode = "lines", ...
                line = struct( ...
                    color = "rgba(0,0,0,1.000000)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                fillcolor = "rgba(0,114,189,1.000000)", ...
                showlegend = true ...
            ));
            tc.verifyEqual(p.data{2}, struct( ...
                xaxis = "x1", ...
                yaxis = "y2", ...
                type = "scatter", ...
                x = x, ...
                y = y2, ...
                name = '', ...
                visible = true, ...
                fill = "tozeroy", ...
                mode = "lines", ...
                line = struct( ...
                    color = "rgba(0,0,0,1.000000)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                fillcolor = "rgba(217,83,25,1.000000)", ...
                showlegend = true ...
            ));
        end

        function testBoxPlotData(tc)
            fig = figure("Visible","off");
            data = [0.4394; -0.0896; 1.0212; -0.8740; 0.4147];
            boxplot(data);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 7);
            tc.verifyEqual(p.data{1}, struct( ...
                type = 'scatter', ...
                mode = 'markers', ...
                visible = true, ...
                name = '', ...
                xaxis = 'x1', ...
                yaxis = 'y1', ...
                x = [NaN NaN], ...
                y = [NaN NaN], ...
                marker = struct( ...
                    size = 3.6, ...
                    symbol = "cross-thin-open", ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(255,0,0)" ...
                ), ...
                line = struct(), ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{2}, struct( ...
                type = 'scatter', ...
                mode = 'lines', ...
                visible = true, ...
                name = '', ...
                xaxis = 'x1', ...
                yaxis = 'y1', ...
                x = [0.9250 1.0750], ...
                y = [0.4147 0.4147], ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(255,0,0)" ...
                ), ...
                line = struct( ...
                    color = "rgb(255,0,0)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{3}, struct( ...
                type = 'scatter', ...
                mode = 'lines', ...
                visible = true, ...
                name = '', ...
                xaxis = 'x1', ...
                yaxis = 'y1', ...
                x = [0.9250 0.9250 1.0750 1.0750 0.9250], ...
                y = [-0.2857 0.58485 0.58485 -0.2857 -0.2857], ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,255)" ...
                ), ...
                line = struct( ...
                    color = "rgb(0,0,255)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{4}, struct( ...
                type = 'scatter', ...
                mode = 'lines', ...
                visible = true, ...
                name = '', ...
                xaxis = 'x1', ...
                yaxis = 'y1', ...
                x = [0.9625 1.0375], ...
                y = [-0.874 -0.874], ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,0)" ...
                ), ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{5}, struct( ...
                type = 'scatter', ...
                mode = 'lines', ...
                visible = true, ...
                name = '', ...
                xaxis = 'x1', ...
                yaxis = 'y1', ...
                x = [0.9625 1.0375], ...
                y = [1.0212 1.0212], ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,0)" ...
                ), ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{6}, struct( ...
                type = 'scatter', ...
                mode = 'lines', ...
                visible = true, ...
                name = '', ...
                xaxis = 'x1', ...
                yaxis = 'y1', ...
                x = [1 1], ...
                y = [-0.874 -0.2857], ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,0)" ...
                ), ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 0.5, ...
                    dash = "dash" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{7}, struct( ...
                type = 'scatter', ...
                mode = 'lines', ...
                visible = true, ...
                name = '', ...
                xaxis = 'x1', ...
                yaxis = 'y1', ...
                x = [1 1], ...
                y = [0.58485 1.0212], ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,0)" ...
                ), ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 0.5, ...
                    dash = "dash" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testContour3PlotData(tc)
            fig = figure("Visible","off");
            [X,Y,Z] = peaks(25);
            contour3(X,Y,Z,20);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(rmfield(p.data{1}, "colorscale"), struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                name = '', ...
                type = "surface", ...
                x = X, ...
                y = Y, ...
                z = Z, ...
                contours = struct( ...
                    z = struct( ...
                        "end", 7.314565743495028, ...
                        start = -5.644469721095063, ...
                        size = 0.682054498136321, ...
                        show = true, ...
                        usecolormap = true, ...
                        width = 1 ...
                    ) ...
                ), ...
                hidesurface = true, ...
                visible = true, ...
                showscale = false, ...
                reversescale = false, ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testFunctionSurfacePlotData(tc)
            fig = figure("Visible","off");
            fsurf(@(x,y) sin(x).*cos(y), [-pi pi -pi pi]);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 2);
            tc.verifyEqual(rmfield(p.data{1}, ["colorscale" "x" "y" "z" "surfacecolor"]), struct( ...
                scene = "scene1", ...
                type = "surface", ...
                opacity = 1, ...
                name = '{sin}({x}) {cos}({y})', ...
                showscale = false, ...
                visible = true, ...
                showlegend = true ...
            ));
            tc.verifyEqual(rmfield(p.data{2}, ["x" "y" "z"]), struct( ...
                scene = "scene1", ...
                type = "scatter3d", ...
                mode = "lines", ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 1.5, ...
                    dash = "solid" ...
                ), ...
                name = '{sin}({x}) {cos}({y})', ...
                showscale = false, ...
                visible = true ...
            ));
        end

        function testIsosurfacePlotData(tc)
            fig = figure("Visible","off");
            [X,Y,Z] = meshgrid(linspace(-1,1,20),linspace(-1,1,20),linspace(-1,1,20));
            V = X.^2 + Y.^2 + Z.^2;
            isosurface(X,Y,Z,V,0.5);

            plotData = fig.Children.Children(2);
            p = plotlyfig(fig,"visible","off","treatAs",'isosurface');

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "mesh3d", ...
                name = '', ...
                showscale = false, ...
                x = plotData.Vertices(:,1), ...
                y = plotData.Vertices(:,2), ...
                z = plotData.Vertices(:,3), ...
                i = plotData.Faces(:,1) - 1, ...
                j = plotData.Faces(:,2) - 1, ...
                k = plotData.Faces(:,3) - 1, ...
                color = "rgb(16,190,186)", ...
                lighting = struct( ...
                    diffuse = 0.6, ...
                    ambient = 0.3, ...
                    specular = 0.9, ...
                    roughness = 0.2, ...
                    fresnel = 0.5, ...
                    vertexnormalsepsilon = 1e-12, ...
                    facenormalsepsilon = 1e-06 ...
                ), ...
                scene = "scene1", ...
                showlegend = false ...
            ));
        end

        function testScatterHistPlotData(tc)
            fig = figure("Visible","off");
            x = [0.15 0.19 0.04 0.64 0.28 0.54 0.70 0.50 0.54 0.45];
            y = [0.12 0.49 0.85 0.87 0.27 0.21 0.56 0.64 0.42 0.21];
            scatterhist(x,y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 3);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = '', ...
                mode = 'markers', ...
                x = x, ...
                y = y, ...
                line = struct(), ...
                marker = struct( ...
                    size = 3.6, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgb(0,114,189)" ...
                    ), ...
                    color = "rgba(0,0,0,0)" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{2}, struct( ...
                xaxis = "x2", ...
                yaxis = "y2", ...
                type = "bar", ...
                name = '', ...
                x = [1.2 0.8], ...
                width = [0.5 0.5], ...
                y = [0.25 0.75], ...
                orientation = "h", ...
                marker = struct( ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgba(0,0,0,1.000000)" ...
                    ), ...
                    color = "rgba(0,114,189,0.600000)" ...
                ), ...
                opacity = 0.75, ...
                visible = true, ...
                showlegend = true ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{3}, struct( ...
                xaxis = "x3", ...
                yaxis = "y3", ...
                type = "bar", ...
                name = '', ...
                x = [0.15 0.45 0.75], ...
                width = [0.3 0.3 0.3], ...
                y = [4/3 4/3 2/3], ...
                marker = struct( ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgba(0,0,0,1.000000)" ...
                    ), ...
                    color = "rgba(0,114,189,0.600000)" ...
                ), ...
                opacity = 0.75, ...
                visible = true, ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testScatterHistPlotLayout(tc)
            fig = figure(Visible="off");
            x = [0.15 0.19 0.04 0.64 0.28 0.54 0.70 0.50 0.54 0.45];
            y = [0.12 0.49 0.85 0.87 0.27 0.21 0.56 0.64 0.42 0.21];
            scatterhist(x,y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyEqual(p.layout.xaxis1.range, [-0.0549, 0.9549], AbsTol=1e-15);
            tc.verifyEqual(p.layout.xaxis1.domain, ...
                    [fig.Children(4).Position(1), sum(fig.Children(4).Position([1 3]))]);
            tc.verifyEqual(p.layout.xaxis1.anchor, "y1");

            tc.verifyEqual(p.layout.yaxis1.range, [-0.061, 1.061], AbsTol=1e-15);
            tc.verifyEqual(p.layout.yaxis1.domain, ...
                    [fig.Children(4).Position(2), sum(fig.Children(4).Position([2 4]))]);
            tc.verifyEqual(p.layout.yaxis1.anchor, "x1");

            tc.verifyEqual(p.layout.xaxis2.range, [-0.012, 1.212]);
            tc.verifyEqual(p.layout.xaxis2.domain, ...
                    [fig.Children(3).Position(1), sum(fig.Children(3).Position([1 3]))]);
            tc.verifyEqual(p.layout.xaxis2.anchor, "y2");

            tc.verifyEqual(p.layout.yaxis2.range, [-0.061, 1.061], AbsTol=1e-15);
            tc.verifyEqual(p.layout.yaxis2.domain, ...
                    [fig.Children(3).Position(2), sum(fig.Children(3).Position([2 4]))]);
            tc.verifyEqual(p.layout.yaxis2.anchor, "x2");

            tc.verifyEqual(p.layout.xaxis3.range, [-0.0549, 0.9549], AbsTol=1e-15);
            tc.verifyEqual(p.layout.xaxis3.domain, ...
                    [fig.Children(2).Position(1), sum(fig.Children(2).Position([1 3]))]);
            tc.verifyEqual(p.layout.xaxis3.anchor, "y3");

            tc.verifyEqual(p.layout.yaxis3.range, [-0.013333333333333332, 1.3466666666666667]);
            tc.verifyEqual(p.layout.yaxis3.domain, ...
                    [fig.Children(2).Position(2), sum(fig.Children(2).Position([2 4]))]);
            tc.verifyEqual(p.layout.yaxis3.anchor, "x3");
        end

        function testGroupedKernelScatterHistPlotData(tc)
            fig = figure("Visible","off");
            x = [0.15 0.19 0.04 0.64 0.28 0.54 0.70 0.50 0.54 0.45];
            y = [0.12 0.49 0.85 0.87 0.27 0.21 0.56 0.64 0.42 0.21];
            species = [repelem("setosa",4) repelem("versicolor",4) repelem("virginica",2)]';

            scatterhist(x,y,"Group",species,"Kernel","on");

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 12);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = 'setosa', ...
                mode = 'markers', ...
                x = x(species == "setosa"), ...
                y = y(species == "setosa"), ...
                line = struct(), ...
                marker = struct( ...
                    size = 3.6, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgb(0,114,189)" ...
                    ), ...
                    color = "rgba(0,0,0,0)" ...
                ), ...
                showlegend = true ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{2}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = 'versicolor', ...
                mode = 'markers', ...
                x = x(species == "versicolor"), ...
                y = y(species == "versicolor"), ...
                line = struct(), ...
                marker = struct( ...
                    size = 3.6, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgb(217,83,25)" ...
                    ), ...
                    color = "rgba(0,0,0,0)" ...
                ), ...
                showlegend = true ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{3}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = 'virginica', ...
                mode = 'markers', ...
                x = x(species == "virginica"), ...
                y = y(species == "virginica"), ...
                line = struct(), ...
                marker = struct( ...
                    size = 3.6, ...
                    symbol = "circle", ...
                    line = struct( ...
                        width = 0.5, ...
                        color = "rgb(237,177,32)" ...
                    ), ...
                    color = "rgba(0,0,0,0)" ...
                ), ...
                showlegend = true ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{4}, []);
            tc.verifyEqual(p.data{5}, struct( ...
                type = "scatter", ...
                xaxis = "x3", ...
                yaxis = "y3", ...
                name = '', ...
                mode = 'lines', ...
                x = fig.Children(3).Children(4).XData, ...
                y = fig.Children(3).Children(4).YData, ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 2, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 2 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                visible = true, ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{6}, struct( ...
                type = "scatter", ...
                xaxis = "x3", ...
                yaxis = "y3", ...
                name = '', ...
                mode = 'lines', ...
                x = fig.Children(3).Children(3).XData, ...
                y = fig.Children(3).Children(3).YData, ...
                line = struct( ...
                    color = "rgb(217,83,25)", ...
                    width = 2, ...
                    dash = "dot" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 2 ...
                    ), ...
                    color = "rgb(217,83,25)" ...
                ), ...
                visible = true, ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{7}, struct( ...
                type = "scatter", ...
                xaxis = "x3", ...
                yaxis = "y3", ...
                name = '', ...
                mode = 'lines', ...
                x = fig.Children(3).Children(2).XData, ...
                y = fig.Children(3).Children(2).YData, ...
                line = struct( ...
                    color = "rgb(237,177,32)", ...
                    width = 2, ...
                    dash = "dashdot" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 2 ...
                    ), ...
                    color = "rgb(237,177,32)" ...
                ), ...
                visible = true, ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{8}, struct( ...
                type = "scatter", ...
                xaxis = "x3", ...
                yaxis = "y3", ...
                name = '', ...
                mode = 'lines', ...
                x = [0.045 0.945], ...
                y = [0 0], ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,0)" ...
                ), ...
                visible = true, ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{9}, struct( ...
                type = "scatter", ...
                xaxis = "x4", ...
                yaxis = "y4", ...
                name = '', ...
                mode = 'lines', ...
                x = fig.Children(2).Children(4).XData, ...
                y = fig.Children(2).Children(4).YData, ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 2, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 2 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                visible = true, ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{10}, struct( ...
                type = "scatter", ...
                xaxis = "x4", ...
                yaxis = "y4", ...
                name = '', ...
                mode = 'lines', ...
                x = fig.Children(2).Children(3).XData, ...
                y = fig.Children(2).Children(3).YData, ...
                line = struct( ...
                    color = "rgb(217,83,25)", ...
                    width = 2, ...
                    dash = "dot" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 2 ...
                    ), ...
                    color = "rgb(217,83,25)" ...
                ), ...
                visible = true, ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{11}, struct( ...
                type = "scatter", ...
                xaxis = "x4", ...
                yaxis = "y4", ...
                name = '', ...
                mode = 'lines', ...
                x = fig.Children(2).Children(2).XData, ...
                y = fig.Children(2).Children(2).YData, ...
                line = struct( ...
                    color = "rgb(237,177,32)", ...
                    width = 2, ...
                    dash = "dashdot" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 2 ...
                    ), ...
                    color = "rgb(237,177,32)" ...
                ), ...
                visible = true, ...
                showlegend = false ...
            ), AbsTol=1e-15);
            tc.verifyEqual(p.data{12}, struct( ...
                type = "scatter", ...
                xaxis = "x4", ...
                yaxis = "y4", ...
                name = '', ...
                mode = 'lines', ...
                x = [-0.026 0.766], ...
                y = [0 0], ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,0)" ...
                ), ...
                visible = true, ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testTitleFont(tc)
            fig = figure("Visible","off");
            x = 1:10;
            y = x;
            plot(x,y);
            title("Custom Title","FontSize",24,"Color","g","FontName","Arial");

            p = plotlyfig(fig,"visible","off");

            annotation = p.layout.annotations{1};
            tc.verifyEqual(annotation.text, "<b><b>Custom Title</b></b>");
            tc.verifyEqual(annotation.font, struct( ...
                color = "rgb(0,255,0)", ...
                family = "Arial, sans-serif", ...
                size = 24 ...
            ));
        end

        function testAxisLabelSizeFont(tc)
            fig = figure("Visible","off");
            x = 1:10;
            y = x;
            plot(x,y);
            xlabel("X Label","FontSize",20,"Color","b", ...
                    FontName ="Comic Sans MS");
            ylabel("Y Label","FontSize",20,"Color","r", ...
                    FontName ="Comic Sans MS");

            p = plotlyfig(fig,"visible","off");

            tc.verifyEqual(p.layout.xaxis1.title, struct( ...
                text = "X Label" ...
            ));
            tc.verifyEqual(p.layout.xaxis1.titlefont, struct( ...
                color = "rgb(0,0,255)", ...
                size = 20, ...
                family = "Droid Sans, sans-serif" ...
            ));
            tc.verifyEqual(p.layout.yaxis1.title, struct( ...
                text = "Y Label" ...
            ));
            tc.verifyEqual(p.layout.yaxis1.titlefont, struct( ...
                color = "rgb(255,0,0)", ...
                size = 20, ...
                family = "Droid Sans, sans-serif" ...
            ));
        end

        function testMeshPlotData(tc)
            fig = figure("Visible","off");
            [X,Y] = meshgrid(linspace(-2,2,15));
            Z = X.*exp(-X.^2-Y.^2);
            mesh(X,Y,Z);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(rmfield(p.data{1}, ["colorscale" "surfacecolor"]), struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "surface", ...
                x = X, ...
                y = Y, ...
                z = Z, ...
                contours = struct( ...
                    x = struct( ...
                        "end", 2, ...
                        start = -2, ...
                        size = 0.285714285714286, ...
                        show = true, ...
                        color = "black" ...
                    ), ...
                    y = struct( ...
                        "end", 2, ...
                        start = -2, ...
                        size = 0.285714285714286, ...
                        show = true, ...
                        color = "black" ...
                    ) ...
                ), ...
                name = '', ...
                showscale = false, ...
                visible = true, ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testRibbonPlotData(tc)
            fig = figure("Visible","off");
            n = 50;
            x = linspace(0,4*pi,n);
            y = [sin(x); sin(x)+0.5; sin(x)+1]';
            ribbon(x,y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 3);
            tc.verifyEqual(rmfield(p.data{1}, ["colorscale" "surfacecolor"]), struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "surface", ...
                x = repmat([0.625 1.375], n, 1), ...
                y = repmat(x(:), 1, 2), ...
                z = repmat(y(:,1), 1, 2), ...
                contours = struct( ...
                    x = struct( ...
                        "end", 1.375, ...
                        start = 0.625, ...
                        size = 0.75, ...
                        show = true, ...
                        color = "black" ...
                    ), ...
                    y = struct( ...
                        "end", max(x), ...
                        start = min(x), ...
                        size = rangeLength(x(:)) / (size(x, 2)-1), ...
                        show = true, ...
                        color = "black" ...
                    ) ...
                ), ...
                name = '', ...
                showscale = false, ...
                visible = true, ...
                showlegend = true ...
            ), AbsTol=1e-15);
        end

        function testPatchPlotData(tc)
            fig = figure("Visible","off");
            x = [0 1 1 0];
            y = [0 0 1 1];
            patch(x, y, "red");

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = 'scatter', ...
                x = [x x(1)], ...
                y = [y y(1)], ...
                name = '', ...
                visible = true, ...
                fill = 'tozeroy', ...
                mode = 'lines', ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    sizeref = 1, ...
                    sizemode = "diameter", ...
                    size = 6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,0)" ...
                ), ...
                fillcolor = "rgba(255,0,0,1.000000)", ...
                showlegend = false ...
            ));
        end

        function testFillPlotData(tc)
            fig = figure("Visible","off");
            x1 = [1 2 3 4 5];
            y1 = [1 2 1 2 1];
            x2 = [1 2 3 4 5];
            y2 = [2 3 2 3 2];
            fill(x1, y1, 'blue', x2, y2, 'green');

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 2);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = 'scatter', ...
                x = [x1 x1(1)], ...
                y = [y1 y1(1)], ...
                name = '', ...
                visible = true, ...
                fill = 'tozeroy', ...
                mode = 'lines', ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    sizeref = 1, ...
                    sizemode = "diameter", ...
                    size = 6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,0)" ...
                ), ...
                fillcolor = "rgba(0,0,255,1.000000)", ...
                showlegend = false ...
            ));
            tc.verifyEqual(p.data{2}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = 'scatter', ...
                x = [x2 x2(1)], ...
                y = [y2 y2(1)], ...
                name = '', ...
                visible = true, ...
                fill = 'tozeroy', ...
                mode = 'lines', ...
                line = struct( ...
                    color = "rgb(0,0,0)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    sizeref = 1, ...
                    sizemode = "diameter", ...
                    size = 6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,0,0)" ...
                ), ...
                fillcolor = "rgba(0,255,0,1.000000)", ...
                showlegend = false ...
            ));
        end

        function testCompassPlotData(tc)
            fig = figure("Visible","off");
            u = [1 2 -1 -2];
            v = [1 -1 1 -1];
            compass(u, v);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 4);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = '', ...
                mode = 'lines', ...
                x = [0 1 0.72 1 0.88], ...
                y = [0 1 0.88 1 0.72], ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testFeatherPlotData(tc)
            fig = figure("Visible","off");
            theta = (0:15:360)*pi/180;
            r = 2*cos(2*theta).^2 + 1;
            u = r.*cos(theta);
            v = r.*sin(theta);
            feather(u, v);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, numel(theta)+1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = '', ...
                mode = 'lines', ...
                x = [1 4 NaN 3.4 4 3.4], ...
                y = [0 0 NaN 0.24 0 -0.24], ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testSemilogyPlotData(tc)
            fig = figure("Visible","off");
            x = 0:0.1:10;
            y = x;
            semilogy(x, y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = '', ...
                mode = 'lines', ...
                x = x, ...
                y = y, ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testSemilogxPlotData(tc)
            fig = figure("Visible","off");
            x = 0:0.1:10;
            y = x;
            semilogx(x, y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            tc.verifyEqual(p.data{1}, struct( ...
                type = "scatter", ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                visible = true, ...
                name = '', ...
                mode = 'lines', ...
                x = x, ...
                y = y, ...
                line = struct( ...
                    color = "rgb(0,114,189)", ...
                    width = 0.5, ...
                    dash = "solid" ...
                ), ...
                marker = struct( ...
                    size = 3.6, ...
                    line = struct( ...
                        width = 0.5 ...
                    ), ...
                    color = "rgb(0,114,189)" ...
                ), ...
                showlegend = false ...
            ), AbsTol=1e-15);
        end

        function testTiledLayoutHeatmap(tc)
            fig = figure("Visible","off");
            data = [1 2; 3 4];
            tiledlayout(2,2);
            for i = 1:4
                nexttile;
                heatmap(data);
            end

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 4);
            tc.verifyEqual(rmfield(p.data{1}, ["colorscale" "colorbar"]), struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "heatmap", ...
                x = {num2cell(num2str((1:2)'))}, ...
                y = {num2cell(num2str(flip(1:2)'))}, ...
                z = flip(data), ...
                zmin = min(data,[],"all"), ...
                zmax = max(data,[],"all"), ...
                connectgaps = false, ...
                hoverongaps = false, ...
                hoverinfo = "text", ...
                text = flip(data), ...
                hoverlabel = struct( ...
                    bgcolor = "white" ...
                ), ...
                showscale = true, ...
                visible = true, ...
                opacity = 0.9500, ...
                showlegend = false, ...
                name = "" ...
            ), AbsTol=1e-15);
            tc.verifyEqual(rmfield(p.data{1}.colorbar, ["thickness" "x"]), struct( ...
                y = fig.Children.Children(4).Position(2), ...
                xanchor = "left", ...
                yanchor = "bottom", ...
                thicknessmode = "fraction", ...
                lenmode = "fraction", ...
                len = fig.Children.Children(4).Position(4), ...
                ypad = 0, ...
                xpad = 10, ...
                outlinecolor = "rgb(150,150,150)" ...
            ), AbsTol=1e-15);
        end

        function testGroupedBarPlotData(tc)
            fig = figure("Visible","off");
            y = [2 5 3; 6 1 4; 3 7 2];
            bar(y);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 3);
            tc.verifyEqual(p.data{1}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                name = '', ...
                visible = true, ...
                orientation = "v", ...
                x = [1 2 3], ...
                y = y(:,1)', ...
                marker = struct( ...
                    color = "rgba(0,114,189,1.000000)", ...
                    line = struct( ...
                        color = "rgba(0,0,0,1.000000)", ...
                        width = 0.5, ...
                        dash = "solid" ...
                    ) ...
                ), ...
                showlegend = true ...
            ));
            tc.verifyEqual(p.data{2}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                name = '', ...
                visible = true, ...
                orientation = "v", ...
                x = [1 2 3], ...
                y = y(:,2)', ...
                marker = struct( ...
                    color = "rgba(217,83,25,1.000000)", ...
                    line = struct( ...
                        color = "rgba(0,0,0,1.000000)", ...
                        width = 0.5, ...
                        dash = "solid" ...
                    ) ...
                ), ...
                showlegend = true ...
            ));
            tc.verifyEqual(p.data{3}, struct( ...
                xaxis = "x1", ...
                yaxis = "y1", ...
                type = "bar", ...
                name = '', ...
                visible = true, ...
                orientation = "v", ...
                x = [1 2 3], ...
                y = y(:,3)', ...
                marker = struct( ...
                    color = "rgba(237,177,32,1.000000)", ...
                    line = struct( ...
                        color = "rgba(0,0,0,1.000000)", ...
                        width = 0.5, ...
                        dash = "solid" ...
                    ) ...
                ), ...
                showlegend = true ...
            ));
        end

        function testHeatmapTextColorBrightCells(tc)
            fig = figure("Visible","off");
            data = [1 2; 3 4];
            h = heatmap(data);
            h.Colormap = repmat([0.9 0.9 0.9], 64, 1); % Light gray colormap

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.layout.annotations, numel(data));
            % All cells should have black text due to bright background
            for i = 1:numel(p.layout.annotations)
                ann = p.layout.annotations{i};
                tc.verifyEqual(ann.font.color, "rgb(0,0,0)"); % Black text
            end
        end

        function testHeatmapTextColorDarkCells(tc)
            fig = figure("Visible","off");
            data = [1 2; 3 4];
            h = heatmap(data);
            h.Colormap = repmat([0.1 0.1 0.1], 64, 1); % Dark gray colormap

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.layout.annotations, numel(data));
            % All cells should have white text due to dark background
            for i = 1:numel(p.layout.annotations)
                ann = p.layout.annotations{i};
                tc.verifyEqual(ann.font.color, "rgb(255,255,255)"); % White text
            end
        end

        function testHeatmapMixedColorCells(tc)
            fig = figure("visible","off");
            data = [ ...
                4.316 3.895 3.176 2.850 2.667 2.429 2.173 1.920;
                4.226 3.847 3.179 2.863 2.688 2.455 2.203 1.954;
                3.951 3.650 3.113 2.824 2.666 2.458 2.224 1.998;
                3.820 3.556 3.091 2.828 2.684 2.495 2.271 2.060;
                3.701 3.459 3.036 2.787 2.650 2.475 2.260 2.062;
                3.490 3.289 2.937 2.706 2.580 2.421 2.227 2.048;
                3.292 3.128 2.820 2.608 2.493 2.353 2.186 2.031;
                3.073 2.939 2.675 2.481 2.377 2.259 2.121 1.992;
            ];
            h = heatmap(data);
            nColors = 256;
            zeroPos = round(0.5 * (nColors-1)) + 1;
            redToWhite = [linspace(1,1,zeroPos)', linspace(0,1,zeroPos)', linspace(0,1,zeroPos)'];
            whiteToGreen = [linspace(1,0,nColors-zeroPos+1)', ...
                            linspace(1,1,nColors-zeroPos+1)', ...
                            linspace(1,0,nColors-zeroPos+1)'];
            customMap = [redToWhite; whiteToGreen(2:end,:)];
            colormap(h, customMap);
            caxis([min(data(:)) max(data(:))]);

            p = plotlyfig(fig,"visible","off");

            isWhite = cellfun(@(ann) ann.font.color == "rgb(255,255,255)", p.layout.annotations);
            positions = cellfun(@(ann) ann.x + "," + ann.y, p.layout.annotations);
            actual = positions(isWhite);
            expected = ["5,0" "6,0" "6,1" "6,2" "6,3" "6,4" "6,5" "6,6" "6,7" "7,0" "7,1" "7,2" "7,3" "7,4" "7,5" "7,6" "7,7"];
            tc.verifyEqual(actual, expected);
        end

        function testHeatmapCellTextAnnotations(tc)
            fig = figure("Visible","off");
            data = [1 2; 3 4; 5 6];
            heatmap(data);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.layout.annotations, numel(data));
            actualStrings = cellfun(@(ann) ann.text, p.layout.annotations);
            expectedStrings = arrayfun(@(v) string(v), data(:));
            tc.verifyEqual(sort(actualStrings(:)), sort(expectedStrings(:)));
        end

        function testHeatmapTitleAnnotation(tc)
            fig = figure("Visible","off");
            data = [1 2; 3 4];
            titleString = "title";
            heatmap(data);
            title(titleString);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.layout.annotations, numel(data)+1);
            actualStrings = cellfun(@(ann) ann.text, p.layout.annotations);
            tc.verifyNotEmpty(actualStrings(contains(actualStrings, titleString)));
        end

        function testHeatmapAxisLabels(tc)
            fig = figure("Visible","off");
            data = [1 2; 3 4];
            xLabelText = "X Axis Label";
            yLabelText = "Y Axis Label";
            heatmap(data);
            xlabel(xLabelText);
            ylabel(yLabelText);

            p = plotlyfig(fig,"visible","off");

            tc.verifyEqual(p.layout.xaxis1.title.text, xLabelText);
            tc.verifyEqual(p.layout.yaxis1.title.text, yLabelText);
        end

        function testHeatmapWithNaNValues(tc)
            fig = figure("Visible","off");
            data = [1 2 NaN; 4 NaN 6; 7 8 9];
            heatmap(data);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            heatmapData = p.data{1};
            tc.verifyEqual(heatmapData.z, flip(data));
        end

        function testHeatmapAllNaNValues(tc)
            fig = figure("Visible","off");
            data = [NaN NaN; NaN NaN];
            heatmap(data);

            p = plotlyfig(fig,"visible","off");

            tc.verifyNumElements(p.data, 1);
            heatmapData = p.data{1};
            tc.verifyEqual(heatmapData.z, flip(data));
            tc.verifyTrue(all(isnan(heatmapData.z(:))));
            tc.verifyTrue(all(isnan(heatmapData.text(:))));
        end
    end
end
